﻿using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace Agile.Service.Rbac
{
    public class LoginResult : Result<string>
    {
        public string ReturnUrl;
        public string Token;
    }
    public interface IAuth
    {
        bool CheckLogin(string token = "", string otherInfo = "");
        AuthStrategyContext GetCurrentUser();
        Task<LoginResult> LoginAsync(string username, string password);
        Task<bool> LogoutAsync();
    }
    /// <summary>
    /// 使用本地登录。这个注入IAuth时，只需要OpenAuth.Mvc一个项目即可，无需webapi的支持
    /// </summary>
    public class LocalAuth : IAuth
    {
        private ILoginInfo _loginInfoy;
        private readonly IUserService _userService;
        private AuthContextFactory _authContextFactory;
        public LocalAuth(ILoginInfo loginInfo, IUserService userService, AuthContextFactory authContextFactory)
        {
            _loginInfoy = loginInfo;
            _userService = userService;
            _authContextFactory = authContextFactory;
        }
        public bool CheckLogin(string token = "", string otherInfo = "")
        {
            return (!string.IsNullOrEmpty(HttpContextCore.Current.User.Identity.Name));
        }

        public AuthStrategyContext GetCurrentUser()
        {
            AuthStrategyContext context = _authContextFactory.GetAuthStrategyContext(_loginInfoy.AccountName);
            return context;
        }

        public async Task<LoginResult> LoginAsync(string username, string password)
        {
            User userInfo = null;
            if (username == "admin" && password.ToLower() == "admin".ToMD5String())
            {
                userInfo = new User();
                userInfo.ID = "admin";
                userInfo.Account = "admin";
                userInfo.Name = "创始人";
                userInfo.Email = "admin@agile.com";
                userInfo.Zipcode = "admin";
                userInfo.Idcard = "admin";
                userInfo.Mobile = "admin";
                userInfo.Status = 0;
                userInfo.TenantId = "0";
                userInfo.Nationality = "";
                userInfo.Password = password;
            }
            else
            {
                userInfo = _userService.GetByName(username);
                if (userInfo == null)
                {
                    return new LoginResult { Success = false, StatusCode = 500, Message = "不存在此用户，请重新输入" };
                }
                if (userInfo.Status == 1)
                {
                    return new LoginResult { Success = false, StatusCode = 500, Message = "该账户暂被锁定,请联系管理员" };
                }
                if (userInfo.Password != password)//登录失败
                {
                    return new LoginResult { Success = false, StatusCode = 500, Message = "密码不正确，请重新输入" };
                }
            }
            //create claims for customer's username and email
            var claims = new List<Claim>();
            claims.Add(new Claim(ClaimsName.Platform,"WEB"));
            claims.Add(new Claim(ClaimsName.LoginTime, DateTime.Now.ToString6()));
            if (!string.IsNullOrEmpty(userInfo.TenantId)) claims.Add(new Claim(ClaimsName.TenantId, userInfo.TenantId));
            if (!string.IsNullOrEmpty(userInfo.ID)) claims.Add(new Claim(ClaimsName.UserID, userInfo.ID));
            if (!string.IsNullOrEmpty(userInfo.Name)) claims.Add(new Claim(ClaimsName.UserName, userInfo.Account));
            if (!string.IsNullOrEmpty(userInfo.Email)) claims.Add(new Claim(ClaimsName.Email, userInfo.Email));
            if (!string.IsNullOrEmpty(userInfo.Mobile)) claims.Add(new Claim(ClaimsName.Phone, userInfo.Mobile));
            var userIdentity = new ClaimsIdentity(claims, Utils.AppName);
            var userPrincipal = new ClaimsPrincipal(userIdentity);
            var authenticationProperties = new AuthenticationProperties
            {
                IsPersistent = true,
                ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
            };
            await HttpContextCore.Current.SignInAsync(Utils.AppName, userPrincipal, authenticationProperties);
            return new LoginResult { Success = true, StatusCode = 200, Message = "登录成功" };
        }

        public async Task<bool> LogoutAsync()
        {
            await HttpContextCore.Current.SignOutAsync(Utils.AppName);
            return true;
        }
    }
}
